<?php

namespace App\Logic\Order;

use App\Core\BaseCore;
use App\Core\BaseModel;
use App\Core\Exception\DefaultException;
use App\Core\Output;
use App\EventHandler\OrderAutoSettleHandler;
use App\Model\Member\MemberModel;
use App\Model\Order\OrderModel;
use App\Logic\Order\Form\SubmitOrderForm;
use App\Logic\Order\Form\OrderListForm;
use App\Util\ArrayHelper;
use App\Util\CommonHelper;
use App\Util\UserIdentityHelper;
use EasySwoole\Component\Singleton;
use EasySwoole\Http\Request;
use EasySwoole\Log\Logger;
use EasySwoole\Mysqli\QueryBuilder;
use EasySwoole\ORM\DbManager;
use EasySwoole\ORM\Exception\Exception;
use EasySwoole\RedisPool\RedisPool;
use Throwable;

class OrderService extends BaseCore
{

    use Singleton;

    /**
     * 订单相关字典项目 getDict
     * @return Output
     * @throws DefaultException
     * @throws Throwable
     */
    public function getDict($request): Output
    {

        return $this->success([
            'order_state'   => ArrayHelper::keyArrayToList(OrderModel::getOrderStateDict()),
        ]);
    }


    /**
     * 订单列表 getLists
     * @param Request $request
     * @return Output
     * @throws DefaultException
     * @throws Exception
     * @throws Throwable
     * @throws \EasySwoole\Mysqli\Exception\Exception
     * @throws \EasySwoole\Redis\Exception\RedisException
     */
    public function getLists(Request $request){
        $params    = $request->getQueryParams();
        $cache     = RedisPool::defer();
        $cache_key = "orderCache:lists:" . json_encode($params + ['_id' => UserIdentityHelper::getId(), '_name' => UserIdentityHelper::getUsername()]);
        if ($cache_data = $cache->get($cache_key)) { //缓存存在
            $data = json_decode($cache_data, true);
        } else {
            $form = new OrderListForm($params, $request);
            $data = $form->lists();
            $cache->set($cache_key, json_encode($data), BaseModel::CACHE_EXPIRE);
        }
        return $this->success($data);
    }

    /**
     * 订单统计
     * 统计订单总数/未完成订单数量/已完成(已退货RETURNED)订单数量/订单总金额/已完成订单提成/已完成订单团队提成/未完成订单总数/未完成订单总金额/未完成订单提成/未完成订单团队提成
     * @param Request $request
     * @return Output
     * @throws DefaultException
     * @throws Exception
     * @throws Throwable
     * @throws \EasySwoole\Mysqli\Exception\Exception
     * @throws \EasySwoole\Redis\Exception\RedisException
     */
    public function statistics(Request $request){
        $params    = $request->getQueryParams();
        $cache     = RedisPool::defer();
        $cache_key = "orderCache:statistics:" . json_encode($params + ['_id' => UserIdentityHelper::getId(), '_name' => UserIdentityHelper::getUsername()]);
        if ($cache_data = $cache->get($cache_key)) { //缓存存在
            $data = json_decode($cache_data, true);
        } else {
            $userId = UserIdentityHelper::getId();
            $where = [
                'user_id' => $userId,
                'order_time' => [date('Y-m-d H:i:s'), '<'],
                'is_delete' => 0
            ];
            $profit_where = $where + [
                'order_state' => [[OrderModel::SETTLED], 'IN']
            ];
            $data = [
//                'unfinished_order_count' => OrderModel::create()->where($unfinished_where)->count('id'),//未完成订单总数
//                'unfinished_user_profit' => OrderModel::create()->where($profit_where)->sum('user_profit'),//未完成订单提成
            ];

            $cache->set($cache_key, json_encode($data), 20);//BaseModel::CACHE_EXPIRE
        }
        return $this->success($data);
    }
    /**
     * 购买
     * @param $data
     * @return Output
     * @throws DefaultException
     * @throws Exception
     * @throws Throwable
     * @throws \EasySwoole\Mysqli\Exception\Exception
     */
    public function create($data) : Output
    {
        $orderForm = new SubmitOrderForm($data);
        return $orderForm->submit();
    }
    private $op = '<';//用于测试的时候调试

    /**每日自动结算-定时任务*/
    public function taskOrderAutoSettle($today = null)
    {
        $today = $today ?? date('Y-m-d');
        $tableMember = MemberModel::create()->getTableName();
        $table = OrderModel::create()->getTableName();
        $sql = "SELECT m.* 
                FROM {$tableMember} m
                LEFT JOIN {$table} o 
                  ON m.id = o.user_id 
                  AND o.order_date = '{$today}' 
                  AND o.is_delete = 0
                WHERE m.score > 0 
                  AND m.last_profit_time < '{$today}' 
                  AND m.is_delete = 0
                  AND o.user_id IS NULL
                LIMIT " . OrderModel::ORDERLIMIT;

        $queryBuild = new QueryBuilder();
        $queryBuild->raw($sql);
        $result = DbManager::getInstance()->query($queryBuild, true);

        if ($staRes = $result->getResult()) {
            foreach ($staRes as $item) {
                /** @var OrderAutoSettleHandler eventOrderAutoSettle */
                \App\Process\LmtJob::getInstance()->createJob('eventOrderAutoSettle', ["id" => $item['id'], 'date' => $today]);
            }

        }
    }
    /**每日自动结算*/
    public function jobOrderAutoSettle($userId, $date)
    {
        $data = [
            'user_id' => $userId,
            'date' => $date,
        ];
        try {
            return $this->create($data);
        } catch (Throwable $e) {
            \EasySwoole\EasySwoole\Logger::getInstance()->error($e->getMessage());
        }
        return true;
    }

    /**
     * 自动绑定发货单
    */
    public function orderShipping($date, $auto = false)
    {
        return $this->success();
    }

    /**按照日期统计出没有发货单号的订单数量*/
    public function countUnshippingOrder(Request $request): Output
    {
        $data = [];
        return $this->success($data);
    }

    /**union统计月份分表数据*/
    public function unionCount($userId)
    {
        $total_order_amount = $total_count = 0;
        $now = date('Y-m-d H:i:s');
        $sql = "SELECT SUM(total_order_amount) `total_order_amount`, SUM(total_count) `total_count` FROM (
            SELECT sum(order_amount) as total_order_amount, count(1) as total_count FROM ss_order WHERE `user_id` = {$userId} AND order_time<'". $now ."' AND `is_delete` = 0 ";
        $sql .= ") `d`";
        $queryBuild = new QueryBuilder();
        $queryBuild->raw($sql);
        $result = DbManager::getInstance()->query($queryBuild, true);
        if ($result->getResult()) {
            foreach ($result->getResult() as $item){
                $total_order_amount += $item['total_order_amount'];
                $total_count += $item['total_count'];
            }
        }
        return [
            'total_order_amount' => $total_order_amount,
            'total_count'        => $total_count
        ];
    }
}
